/***************************************************************************************************************
 *   Author : Manu Joseph
 *   Date : 05/05/2010
 *   Description : A tool that easily allow users to share folders and set permissions
 *   File Name : ContactManager.cs
 *   Purpose : Manages operations with the contacts database
****************************************************************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.OleDb;
using System.Diagnostics;
using System.Data;
using System.IO;

namespace EasyShare
{
    /// <summary>
    /// Class which manages contacts in Access database
    /// </summary>
    public class ContactManager
    {
        #region Private Instance Members

        private string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source="; // data source filled by constructor
        private OleDbConnection dbConnection = null;

        #endregion

        #region Construtor

        public ContactManager()
        {
            try
            {
                string strDBFilePath = "'" + Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) +
                                        Path.DirectorySeparatorChar + EasyShareConstants.DB_FILENAME + "'";
                connectionString += strDBFilePath;
                dbConnection = new OleDbConnection(connectionString);
                dbConnection.Open();
            }
            catch (OleDbException ex)
            {
                Trace.WriteLine("Could not open database connection : " + ex.ToString());
                dbConnection.Close();
            }
        }        

        #endregion

        /// <summary>
        /// Returns all contacts, sorted by ShareCount
        /// in a datatable
        /// </summary>
        /// <param name="ContactsTable"></param>
        /// <returns></returns>
        public bool GetAllContacts(ref DataTable ContactsTable)
        {
            if (dbConnection != null)
            {
                try
                {
                    ContactsTable = new DataTable();
                    string queryString = "SELECT Name,Alias FROM Contacts order by ShareCount desc";
                    OleDbCommand dbCommand = new OleDbCommand(queryString, dbConnection);
                    OleDbDataAdapter dbAdapter = new OleDbDataAdapter(dbCommand);
                    dbAdapter.Fill(ContactsTable);
                    return true;
                }
                catch (OleDbException ex)
                {
                    Trace.WriteLine("Exception while reading from database: " + ex.ToString());
                    return false;
                }
                catch (InvalidOperationException ex) // if connection is already closed
                {
                    Trace.WriteLine("Exception while reading from database: " + ex.ToString());
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Updates contact with given contactName
        /// if it fails adds it as a new contact
        /// </summary>
        /// <param name="contactName"></param>
        /// <param name="contactAlias"></param>
        /// <returns></returns>
        public bool SaveContact(string contactName, string contactAlias)
        {
            if (dbConnection != null)
            {
                try
                {
                    // try and update the command first
                    string updateString = "UPDATE Contacts SET Alias='" + contactAlias + "'" +
                                            " WHERE Name='" + contactName + "'";
                    OleDbCommand updateCommand = new OleDbCommand(updateString, dbConnection);
                    int updatedRows = updateCommand.ExecuteNonQuery();
                    if (updatedRows == 0)
                    {
                        // updation failed -- no row with given name
                        // so try and insert
                        string insertString = "INSERT INTO Contacts(Name,Alias) Values('" + contactName + "'" +
                                                ",'" + contactAlias + "')";
                        OleDbCommand insertCommand = new OleDbCommand(insertString, dbConnection);
                        insertCommand.ExecuteNonQuery();
                    }
                    return true;
                }
                catch (OleDbException ex)
                {
                    Trace.WriteLine("Exception while updating to database: " + ex.ToString());
                    return false;
                }
                catch (InvalidOperationException ex) // if connection is already closed
                {
                    Trace.WriteLine("Exception while updating to database: " + ex.ToString());
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Increments the share count of all the users by 1
        /// </summary>
        /// <param name="users"></param>
        /// <returns></returns>
        public bool IncrementShareCount(User[] users)
        {
            if (users == null)
            {
                throw new ArgumentException("users array cannot be null");
            }
            
            try
            {
                if (users.Length > 0)
                {
                    // Construct the user names string
                    StringBuilder usersString = new StringBuilder();
                    for (int i = 0; i < users.Length; i++)
                    {
                        usersString.Append('\'');
                        usersString.Append(users[i].UserName);
                        usersString.Append('\'');
                        usersString.Append(',');
                    }
                    if (usersString.Length > 0)
                    {
                        usersString.Remove(usersString.Length - 1, 1);
                    }

                    // increment the sharecount
                    string incrementString = "UPDATE Contacts SET ShareCount = (ShareCount + 1)" +
                                            " WHERE Name IN (" + usersString.ToString() + ")";
                    OleDbCommand incrementCommand = new OleDbCommand(incrementString, dbConnection);
                    incrementCommand.ExecuteNonQuery(); 
                }

                return true;
            }
            catch (OleDbException ex)
            {
                Trace.WriteLine("Exception while updating to database: " + ex.ToString());
                return false;
            }
            catch (InvalidOperationException ex) // if connection is already closed
            {
                Trace.WriteLine("Exception while updating to database: " + ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// Deletes the given set of contacts
        /// </summary>
        /// <param name="contacts"></param>
        /// <returns></returns>
        public bool DeleteContacts(string[] contacts)
        {
            if (contacts == null)
            {
                throw new ArgumentException("contacts array cannot be null");
            }
            
            try
            {
                if (contacts.Length > 0)
                {
                    StringBuilder contactsString = new StringBuilder();
                    for (int i = 0; i < contacts.Length; i++)
                    {
                        contactsString.Append('\'');
                        contactsString.Append(contacts[i]);
                        contactsString.Append('\'');
                        contactsString.Append(',');
                    }
                    if (contactsString.Length > 0)
                    {
                        contactsString.Remove(contactsString.Length - 1, 1);
                    }

                    string deleteString = "Delete from Contacts" +
                                          " WHERE Name IN (" + contactsString.ToString() + ")";
                    OleDbCommand deleteCommand = new OleDbCommand(deleteString, dbConnection);
                    deleteCommand.ExecuteNonQuery();                    
                }

                return true;
            }
            catch (OleDbException ex)
            {
                Trace.WriteLine("Exception while deleting from database: " + ex.ToString());
                return false;
            }
            catch (InvalidOperationException ex) // if connection is already closed
            {
                Trace.WriteLine("Exception while deleting from database: " + ex.ToString());
                return false;
            }
        }
    }
}
